;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016 Mathieu Lirzin <mthl@gnu.org>
;;; Copyright © 2016, 2017, 2018, 2019 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
;;; Copyright © 2017 Jan Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2018, 2019 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2018 Clément Lassieur <clement@lassieur.org>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation, either version 3 of the License, or
;;; (at your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gpg-agent)
  #:use-module (guix gexp)
  #:use-module (guix records)
  #:use-module (gnu packages admin)
  ;; #:autoload   (gnu packages ci) (cuirass)
  ;; #:autoload   (gnu packages version-control) (git)
  #:use-module (gnu services)
  #:use-module (gnu services base)
  #:use-module (gnu services shepherd)
  #:use-module (gnu services admin)
  #:use-module (gnu system shadow)
  #:export (<gpg-agent-configuration>
            gpg-agent-configuration
            gpg-agent-configuration?
            user
            group
            default-cache-ttl
            pinetry-program
            allow-loopback?
            enable-ssh-support?
            emacs-allow-pinetry?
            gpg-agent-service-type))

;;;; Commentary:
;;; This file provides a shepherd service to run the gpg agent.
;;;; Code:

(define-record-type* <gpg-agent-configuration>
  gpg-agent-configuration make-gpg-agent-configuration
  gpg-agent-configuration?
  (gpg-agent                gpg-agent-configuration-gpg-agent ;package
                            (default gpg-agent))
  (user                     gpg-agent-configuration-user ;string
                            (default "gpg-agent"))
  (group                    gpg-agent-configuration-group ;string
                            (default "gpg-agent"))
  (default-cache-ttl        gpg-agent-configuration-default-cache-ttl ;number
    (default 28800))
  (pinentry-program         gpg-agent-configuration-pinentry-program ;boolean
                            (default "pinentry-gtk-2"))
  (allow-loopback?          gpg-agent-configuration-allow-loopback
                            (default #t))
  (enable-ssh-support?      gpg-agent-configuration-enable-ssh-support
                            (default #t))
  (emacs-allow-pinetry? gpg-agent-configuration-emacs-allow-pinetry
                        (default #f)))

(define (gpg-agent-shepherd-service config)
  "Return a <shepherd-service> for the Gpg-Agent service."
  (let ((gpg-agent                gpg-agent-configuration-gpg-agent)
        (user                     gpg-agent-configuration-user)
        (group                    gpg-agent-configuration-group)
        (default-cache-ttl        gpg-agent-configuration-cache-ttl)
        (allow-loopback?          gpg-agent-configuration-allow-loopback)
        (enable-ssh-support?      gpg-agent-configuration-enable-ssh-support)
        (emacs-allow-pinetry? gpg-agent-configuration-emacs-allow-pinetry))
    (list (shepherd-service
           (documentation "Run Gpg-Agent.")
           (provision '(gpg-agent))
           ;;(requirement '(networking))
           (start #~(make-forkexec-constructor
                     (list (string-append #$gpg-agent "/bin/gpg-agent")
                           " "
                           #$@(if default-cache-ttl    '("--default-cache-ttl ") '())
                           #$@(if allow-loopback?      '("--allow-loopback") '())
                           #$@(if enable-ssh-support?  '("--enable-ssh-support?") '())
                           #$@(if emacs-allow-pinetry? '("--emacs-allow-pinetry")))

                     #:environment-variables
                     (list "GPG_TTY=$(tty)")

                     #:user #$user
                     #:group #$group
                     ))
           (stop #~(make-kill-destructor))))))

(define gpg-agent-service-type
  (service-type
   (name 'gpg-agent)
   (extensions
    (list
     (service-extension shepherd-service-type      ;for 'info gpg-agent'
                        (compose list gpg-agent-configuration-gpg-agent))
     ))
   (description
    "Run GPG's agent.")))
